<template>
  <div>
    <CategorySelector :isDisable="!isShowAttrList"/>
    <el-card style="margin-top:10px;">
      <div v-if="isShowAttrList">
        <el-button type="primary" :icon="Plus" :disabled="!categoryStore.category3Id" @click="toSaveAttr">添加属性</el-button>
        <el-table border :data="attrList" style="margin-top:10px;">
          <el-table-column label="序号" type="index" align="center" width="80"></el-table-column>
          <el-table-column label="属性名称" prop="attrName" width="160"></el-table-column>
          <el-table-column label="属性值列表">
            <template v-slot="{row}">
              <el-tag v-for="attrValue in row.attrValueList" :key="attrValue.id" style="margin-right:6px;">{{attrValue.valueName}}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="200">
            <template v-slot="{row,$index}">
              <el-button title="编辑属性" type="primary" :icon="Edit" size="small" @click="toEditAttr(row)"></el-button>

              <el-popconfirm title="您真的要删除此属性吗?" @confirm="confirmEvent(row,$index)" @cancel="cancelEvent">
                <template #reference>
                  <el-button title="删除属性" type="danger" :icon="Delete" size="small"></el-button>
                </template>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-else>
        <el-card>
          <el-form>
            <el-form-item label="属性名">
              <el-input placeholder="请输入属性名" v-model="attrInfo.attrName" style="width:30%"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button :icon="Plus" type="primary" :disabled="!attrInfo.attrName" @click="toAddAttrValue">添加属性值</el-button>
              <el-button>取消</el-button>
            </el-form-item>
          </el-form>
          <el-table border :data="attrInfo.attrValueList" style="margin-bottom:10px;">
            <el-table-column label="序号" type="index" align="center" width="80" />
            <el-table-column label="属性值名称">
              <template v-slot="{row,$index}">
                <el-input ref="inputRef" size="small" v-if="row.isShowInput" v-model="row.valueName" @blur="deleteCurrentRow(row,$index)"></el-input>
                <span v-else style="display:inline-block;width: 100%;" @dblclick="toEditAttrValue(row)">{{ row.valueName }}</span>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template v-slot="{row,$index}">
                <el-popconfirm title="您真的要删除此属性值吗?" @confirm="toDeleteAttrValue($index)">
                  <template #reference>
                    <el-button title="删除属性值" size="small" type="danger" :icon="Delete"></el-button>
                  </template>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
          <el-button type="primary" :disabled="!attrInfo.attrValueList.length" @click="toSaveOrUpdateAttrInfo">保存</el-button>
          <el-button @click="isShowAttrList=true">取消</el-button>
        </el-card>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
export default {
  name: 'Attr'
};
</script>
<script setup lang="ts">
import { reactive, ref, watch, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { InputInstance } from 'element-plus';
import { Plus, Edit, Delete } from '@element-plus/icons-vue';
import { reqDeleteAttrInfo, reqGetAttrListData, reqSaveAttrInfoData } from '@/api/product/attr';
import { useCategoryListStore } from '@/stores/categoryList';
import type { attrInfoModel,attrValueInfoModel } from '@/api/product/model/attrModel';
// 获取对应的store对象
const categoryStore = useCategoryListStore();
const isShowAttrList = ref(true);
// 为了保持响应式效果 当前这个数组需要使用ref来定义
const attrList = ref<attrInfoModel[]>([]);

const inputRef = ref<InputInstance>();

// 定义一个添加属性时的对象
const attrInfo = reactive<attrInfoModel>({
  attrName: '', // 属性名
  attrValueList: [], // 属性值列表 是一个数组
  categoryId: 0,
  // categoryId:categoryStore.category3Id,
  categoryLevel: 3 // 三级分类id
});

// 1. 根据三级导航id来 获取属性列表
const getAttrListData = async () => {
  const result = await reqGetAttrListData({
    category1Id: categoryStore.category1Id,
    category2Id: categoryStore.category2Id,
    category3Id: categoryStore.category3Id
  });
  // console.log('rr',result)
  attrList.value = result;
};
// 2. 监听三级导航的变化 只要三级导航一旦发生了变化 就要重新发送请求
watch(
  () => categoryStore.category3Id,
  () => {
    // console.log('cc','三级导航数据发生了变化了...')
    if (!categoryStore.category3Id) {
      attrList.value = [];
      return;
    }
    getAttrListData();
  },
  { immediate: true }
);

// 3. 删除属性
const confirmEvent = async (row:attrInfoModel, index:number) => {
  // console.log('confirm!')
  const result = await reqDeleteAttrInfo(row.id as number);
  ElMessage.success('删除属性成功了...');

  // 重新获取属性列表 渲染到页面上
  // getAttrListData()

  // 从attrList数组中根据索引删除数据 用剩余的数据重新渲染列表
  attrList.value.splice(index, 1);
  // 删除成功之后 为什么要重新获取一下剩余的数据?
  // 1. 有可能当前你在做删除属性的时候，刚好有同事在做添加属性
  // 2. 因此 此时在删除完成的时候， 要重新获取最新的数据
  // 3. 如果说 当前的这个业务模块有很少的人在操作 假如说是一个人 这个时候 在删除的时候就无法添加
  //     在添加属性的同时，就无法删除属性 也就是同一时间只能做一件事 鉴于这种操作的时候，我们就可以少发一次请求
};
// 4. 取消删除属性
const cancelEvent = () => {
  ElMessage({
    type: 'info',
    message: '取消删除属性了...'
  });
};

// 5. 添加属性值 其实就是给attrInfo.attrValueList数组添加数据
const toAddAttrValue = () => {
  // 收集具体属性值的对象，相当于是在此处定义的
  attrInfo.attrValueList.push({
    // attrId: -1,
    // attrId: attrInfo.categoryId, // 不加也可以
    valueName: '',
    isShowInput: true // 是否显示输入框
  });

  // 页面中数据的渲染是异步的 要注意让页面中的数据渲染完毕之后再处理后续逻辑
  nextTick(() => {
    inputRef.value?.focus();
  });
};

// 6. 失去焦点时 删除当前项  在这里还有一个业务是实现span标签的切换
const deleteCurrentRow = (row:attrValueInfoModel, index: number) => {
  // if (!row.valueName.trim()) {
  //   attrInfo.attrValueList.splice(index, 1)
  //   return
  // }
  // 6.1 如果当前输入框为空 则要将当前项删除掉
  if (!row.valueName.trim()) return attrInfo.attrValueList.splice(index, 1);

  // 6.2 如果当前输入框不为空 但是呢 失去焦点了 应该要显示span标签 也就是要实现切换
  row.isShowInput = false;
};

// 7. 重新编辑属性值
const toEditAttrValue = (row:attrValueInfoModel) => {
  // 7.1 实现span与input的切换
  row.isShowInput = true;

  // 7.2 让当前项自动获取焦点
  nextTick(() => {
    inputRef.value?.focus();
  });
};

// 8. 删除属性值
const toDeleteAttrValue = (index: number) => {
  attrInfo.attrValueList.splice(index, 1);
};

// 9. 添加或是更新属性
const toSaveOrUpdateAttrInfo = async () => {
  // 9.0 在真正的添加之前，先重新获取一下三级分类的id
  attrInfo.categoryId = categoryStore.category3Id as number
  // 9.1 发送请求添加属性
  await reqSaveAttrInfoData(attrInfo)

  // 更新成功之后 立即删除掉id
  // 9.2 弹出提示框进行提示
  ElMessage.success('添加属性成功...')

  // 9.3 切换到属性列表页
  isShowAttrList.value = true

  // 9.4 重新获取一下属性列表
  getAttrListData()
}

// 10. 添加属性时清空之前的旧属性数据
const toSaveAttr = () => {
  // 10.1 实现属性列表和添加属性的切换
  isShowAttrList.value = false 

  // 10.2 将之前的旧数据清空
  attrInfo.attrName = ''
  attrInfo.attrValueList = []

  // 将attrInfo中的id也删除掉
  delete attrInfo.id
}

// 11. 编辑属性之数据回显
const toEditAttr = (row:attrInfoModel) => {
  // console.log('rr',row)
  // 11.1 先切换到添加属性的界面
  isShowAttrList.value = false 
  // 11.2 给attrInfo赋值
  // attrInfo = row  // 不要直接这样来赋值  容易丢失响应式
  Object.assign(attrInfo,row)
}

// 12. 实现属性更新
</script>
<style>
</style>